package market

import (
	"encoding/json"
	"fmt"
	"git.mycaigou.com/gfyx/common/authorize"
	"git.mycaigou.com/gfyx/common/cache"
	"git.mycaigou.com/gfyx/common/rpc_client"
	"git.mycaigou.com/gfyx/micro-gfyx-api/http_server/controller"
	"git.mycaigou.com/gfyx/micro-gfyx-api/infrastructure/common/constants"
	"git.mycaigou.com/gfyx/micro-gfyx-api/infrastructure/common/errcode"
	dto "git.mycaigou.com/gfyx/micro-gfyx-api/infrastructure/dto/market"
	"git.mycaigou.com/gfyx/micro-gfyx-api/infrastructure/utils"
	pb "git.mycaigou.com/gfyx/micro-gfyx-api/proto/micro_gfyx_oppty_service_proto/micro-gfyx-oppty-service/market"
	"git.mycaigou.com/gfyx/micro-gfyx-api/service/market/outbound_account"
	"git.myscrm.cn/golang/common/ykerrcode"
	"git.myscrm.cn/golang/stark/v4"
	"github.com/gin-gonic/gin"
	"time"
)

type OutboundAccountController struct {
	controller.BaseController
	outboundAccountService outbound_account.OutboundAccountServiceIface
}

func NewOutboundAccountController(outboundAccountService outbound_account.OutboundAccountServiceIface) *OutboundAccountController {
	return &OutboundAccountController{
		outboundAccountService: outboundAccountService,
	}
}

func (c *OutboundAccountController) RegisterRouter(g *gin.RouterGroup) {
	g.GET("account/seat-info-list", c.GetSeatInfoList)
	g.GET("account/robot-list", c.GetRobotList)
	g.GET("account/phone-list", c.GetPhoneList)
	g.GET("account/detail", c.GetAccountDetail)
	g.POST("account/save", c.SaveAccount)
	g.GET("account/expense-detail", c.ExpenseDetail)
}

// GetSeatInfoList 获取坐席列表
func (c *OutboundAccountController) GetSeatInfoList(ctx *gin.Context) {
	companyId, err := utils.GetByCompanyId(ctx, authorize.GetTenantCode(ctx))
	if err != nil || companyId == 0 {
		c.Fail(ctx, errcode.OutboundCompanyIdNotExistError, "Company Id 未设置，请先设置之后再重新尝试")
		return
	}
	response, err := c.outboundAccountService.GetSeatInfoList(ctx, companyId)
	if err != nil {
		stark.Logger.Info(ctx, "GetSeatInfoList-failed: "+err.Error())
		grpcErr := rpc_client.GetGrpcError(err)
		c.Fail(ctx, grpcErr.GetCode(), grpcErr.GetMessage())
		return
	}
	c.Success(ctx, response)
}

// GetRobotList 获取话术列表
func (c *OutboundAccountController) GetRobotList(ctx *gin.Context) {
	companyId, err := utils.GetByCompanyId(ctx, authorize.GetTenantCode(ctx))
	if err != nil || companyId == 0 {
		c.Fail(ctx, errcode.OutboundCompanyIdNotExistError, "Company Id 未设置，请先设置之后再重新尝试")
		return
	}
	response, err := c.outboundAccountService.GetRobotList(ctx, companyId)
	if err != nil {
		stark.Logger.Info(ctx, "GetRobotList-failed: "+err.Error())
		grpcErr := rpc_client.GetGrpcError(err)
		c.Fail(ctx, grpcErr.GetCode(), grpcErr.GetMessage())
		return
	}
	c.Success(ctx, response)
}

// GetPhoneList 获取线路列表
func (c *OutboundAccountController) GetPhoneList(ctx *gin.Context) {
	companyId, err := utils.GetByCompanyId(ctx, authorize.GetTenantCode(ctx))
	if err != nil || companyId == 0 {
		c.Fail(ctx, errcode.OutboundCompanyIdNotExistError, "Company Id 未设置，请先设置之后再重新尝试")
		return
	}
	response, err := c.outboundAccountService.GetPhoneList(ctx, companyId)
	if err != nil {
		stark.Logger.Info(ctx, "GetPhoneList-failed: "+err.Error())
		grpcErr := rpc_client.GetGrpcError(err)
		c.Fail(ctx, grpcErr.GetCode(), grpcErr.GetMessage())
		return
	}
	c.Success(ctx, response)
}

func (c *OutboundAccountController) GetAccountDetail(ctx *gin.Context) {
	// 校验参数
	request := dto.GetAccountDetailRequest{}
	if err := ctx.ShouldBindQuery(&request); err != nil {
		c.Fail(ctx, errcode.COMMON_PARAMS_ERROR, utils.GetValidateErr(request, err))
		stark.Logger.Info(ctx, "GetAccountDetail: "+err.Error())
		return
	}
	// 获取数据
	response, err := c.outboundAccountService.GetAccountDetail(ctx, &request)
	if err != nil {
		stark.Logger.Info(ctx, "GetAccountDetail-failed: "+err.Error())
		grpcErr := rpc_client.GetGrpcError(err)
		c.Fail(ctx, grpcErr.GetCode(), grpcErr.GetMessage())
		return
	}
	c.Success(ctx, response)
}

func (c *OutboundAccountController) SaveAccount(ctx *gin.Context) {
	// 校验参数
	request := dto.SaveAccountRequest{}
	if err := ctx.ShouldBindJSON(&request); err != nil {
		c.Fail(ctx, errcode.COMMON_PARAMS_ERROR, utils.GetValidateErr(request, err))
		stark.Logger.Info(ctx, "SaveAccount: "+err.Error())
		return
	}
	// 获取用户id
	var userId int64
	if val, ok := ctx.Value(constants.LoginUserId).(int64); ok {
		userId = val
	}
	response, err := c.outboundAccountService.SaveAccount(ctx, userId, &request)
	if err != nil {
		stark.Logger.Info(ctx, "SaveAccount-failed: "+err.Error())
		grpcErr := rpc_client.GetGrpcError(err)
		c.Fail(ctx, grpcErr.GetCode(), grpcErr.GetMessage())
		return
	}
	c.Success(ctx, response)
}

func (c *OutboundAccountController) ExpenseDetail(ctx *gin.Context) {
	// 校验参数
	request := &pb.ExpenseDetailRequest{}
	companyId, err := utils.GetByCompanyId(ctx, authorize.GetTenantCode(ctx))
	if err != nil || companyId == 0 {
		c.Fail(ctx, errcode.OutboundCompanyIdNotExistError, "Company Id 未设置，请先设置之后再重新尝试")
		return
	}
	request.CompanyId = companyId

	cacheRedis, _ := cache.Redis()
	currentTime := time.Now()
	// 格式化为年月日
	currFormattedDate := currentTime.Format("2006-01-02")
	// 按天缓存
	cacheKey := fmt.Sprintf("gfyx-ExpenseDetail-%d-%s", companyId, currFormattedDate)
	cacheData, err := cacheRedis.Get(ctx, cacheKey)
	if err != nil {
		stark.Logger.Errorf(ctx, "ExpenseDetail-from-cache: cacheKey:%s, err: %+v", cacheKey, err)
		c.Fail(ctx, ykerrcode.CACHE_ERR, err.Error())
		return
	}
	response := &dto.ExpenseDetailResponse{}
	if cacheData != "" {
		// 走缓存
		err = json.Unmarshal([]byte(cacheData), &response)
		if err != nil {
			stark.Logger.Errorf(ctx, "ExpenseDetail-Unmarshal: cacheData:%s, err: %+v", cacheData, err)
			c.Fail(ctx, errcode.COMMON_ERROR, err.Error())
			return
		}
	} else {
		// 不走缓存，从grpc接口拿
		response, err = c.outboundAccountService.ExpenseDetail(ctx, request)
		if err != nil {
			stark.Logger.Info(ctx, "ExpenseDetail-failed: "+err.Error())
			grpcErr := rpc_client.GetGrpcError(err)
			c.Fail(ctx, grpcErr.GetCode(), grpcErr.GetMessage())
			return
		}
		if response != nil && response.BillingModel != "" {
			responseMarshal, err := json.Marshal(response)
			if err != nil {
				stark.Logger.Errorf(ctx, "ExpenseDetail-Marshal: response:%s, err: %+v", response, err)
			}
			_, err = cacheRedis.Set(ctx, cacheKey, string(responseMarshal), true, 3600*24)
			if err != nil {
				stark.Logger.Errorf(ctx, "ExpenseDetail-from-cache: set cacheData:%s, err: %+v", string(responseMarshal), err)
			}
		}
	}

	if len(response.DetailList) > 0 {
		if response.DetailList[0].Date == currFormattedDate {
			response.DetailList = response.DetailList[1:]
		}
	}
	c.Success(ctx, response)
	return
}
